import { ref, onMounted } from 'vue';
import Iphone15 from '@/assets/phone-prototype/iphone15.png';
import dynamicIslandUrl from '@/assets/phone-prototype/is-dynamic-Island.png';
import { v4 } from 'uuid';

export function usePhoneCanvas({ imgUrl, width = 375, height = 667 }) {
  const tempCanvasId = `wallpaperTempCanvas_${v4()}`;

  console.log(imgUrl, width, height, '=================');

  const dpr = 1;

  const canvas = ref();
  const context = ref();

  const canvasInfo = ref({ width: 0, height: 0 });
  const phoneImgInfo = ref({ node: null, width: 0, height: 0 });
  const imgInfo = ref({ node: null, width: 0, height: 0 });
  const islandInfo = ref({ node: null, width: 0, height: 0 });

  const initCanvas = () => {
    let cvs = document.createElement('canvas');
    // const cvs = document.getElementById(tempCanvasId);
    const ctx = cvs.getContext('2d');

    console.log(cvs, ctx, dpr);
    console.log(cvs.width, cvs.height, 'width height');
    console.log(cvs.clientWidth, cvs.clientHeight, 'clientWidth clientHeight');

    cvs.width = width * dpr;
    cvs.height = height * dpr;

    // ctx.scale(dpr, dpr);

    canvasInfo.value.width = cvs.width;
    canvasInfo.value.height = cvs.height;

    canvas.value = cvs;
    context.value = ctx;
  };

  const initImage = async () => {
    // 初始化模型图片
    const modelImgData = await onLoadImageEndSize(Iphone15);
    phoneImgInfo.value.node = modelImgData.node;
    phoneImgInfo.value.width = modelImgData.width;
    phoneImgInfo.value.height = modelImgData.height;

    // 初始化图片
    const imgData = await onLoadImageEndSize(imgUrl);
    imgInfo.value.node = imgData.node;
    imgInfo.value.width = imgData.width;
    imgInfo.value.height = imgData.height;

    // 初始化灵动岛
    const islandData = await onLoadImageEndSize(dynamicIslandUrl);
    islandInfo.value.node = islandData.node;
    islandInfo.value.width = islandData.width;
    islandInfo.value.height = islandData.height;

    console.log(canvasInfo.value, 'canvasInfo.value');
    console.log(phoneImgInfo.value, 'phoneImgInfo.value');
    console.log(imgInfo.value, 'imgInfo.value');
    console.log(islandInfo.value, 'islandInfo.value');
  };

  const onLoadImageEndSize = async (url) => {
    if (!url) return;
    return new Promise((resolve, reject) => {
      // let image = document.createElement('img');
      const image = new Image();
      image.crossOrigin = 'Anonymous'; // 加这句
      image.src = url;
      image.onload = () => resolve({ node: image, width: image.width, height: image.height });
      image.onerror = reject;
    });
  };

  const onDrawPointData = () => {
    const scale = phoneImgInfo.value.width / phoneImgInfo.value.height;

    const thresholdHeight = canvasInfo.value.height * 0.02 * 2;

    const height = canvasInfo.value.height - thresholdHeight;

    const width = phoneImgInfo.value.width * scale;

    console.log(width, height, scale, 'pscale');

    const x = (canvasInfo.value.width - width) / 2;
    const y = (canvasInfo.value.height - height) / 2;

    return { x, y, width, height, scale };
  };

  const onPhoneModelDraw = async () => {
    context.value.save();

    const node = phoneImgInfo.value.node;

    const { x, y, width, height } = onDrawPointData();

    context.value.drawImage(node, x, y, width, height);

    context.value.restore();
  };

  const onDynamicIslandDraw = () => {
    context.value.save();

    const node = islandInfo.value.node;
    const width = canvasInfo.value.width * 0.22;
    const scale = width / islandInfo.value.width;
    const height = islandInfo.value.height * scale;

    const x = (canvasInfo.value.width - width) / 2;

    const point_y = onDrawPointData().y;

    const y = point_y + height / 1.5;

    context.value.drawImage(node, x, y, width, height);

    context.value.restore();
  };

  const onImgDraw = () => {
    context.value.save();

    const node = imgInfo.value.node;

    const pointData = onDrawPointData();

    const imgRatio = imgInfo.value.width / imgInfo.value.height;

    const modelRatio = pointData.scale;

    let sourceX, sourceY, sourceWidth, sourceHeight;

    if (imgRatio > modelRatio) {
      // 图片更宽，按高度裁剪
      sourceHeight = imgInfo.value.height;
      sourceWidth = sourceHeight * modelRatio;
      sourceX = (imgInfo.value.width - sourceWidth) / 2;
      sourceY = 0;
    } else {
      // 图片更高，按宽度裁剪
      sourceWidth = imgInfo.value.width;
      sourceHeight = sourceWidth / modelRatio;
      sourceX = 0;
      sourceY = (imgInfo.value.height - sourceHeight) / 2;
    }

    console.log(
      {
        sourceX,
        sourceY, // 源图片裁剪起点
        sourceWidth,
        sourceHeight, // 源图片裁剪尺寸
      },
      'sourceWidth',
    );

    // 绘制矩形
    drawRoundedRect(
      context.value,
      pointData.x,
      pointData.y,
      pointData.width,
      pointData.height,
      canvasInfo.value.height * 0.15,
    );

    // 裁剪路径
    context.value.clip();

    context.value.drawImage(
      node,
      sourceX, // 源图片裁剪起点
      sourceY,
      sourceWidth, // 源图片裁剪尺寸
      sourceHeight,
      pointData.x + 5,
      pointData.y + 5,
      pointData.width - 10,
      pointData.height - 10,
    );

    context.value.restore();
  };

  // 绘制圆角矩形函数
  function drawRoundedRect(ctx, x, y, width, height, radius) {
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();
  }

  const onDraw = () => {
    onImgDraw();
    onPhoneModelDraw();
    onDynamicIslandDraw();
  };

  const toDataURL = async () => {
    initCanvas();
    await initImage();
    onDraw();
    console.log(canvas.value, 'canvas.value');

    return canvas.value.toDataURL('image/png');
  };

  onMounted(() => {
    setTimeout(async () => {
      if (imgUrl) {
      }
    });
  });

  return { toDataURL };
}
